package org.dromara.demo.controller;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.ServletOutputStream;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.excel.convert.ExcelBigNumberConvert;
import org.dromara.demo.domain.vo.JsFileVo;
import org.dromara.demo.service.IJsFileService;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysUserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.demo.domain.vo.JsExecuteVo;
import org.dromara.demo.domain.bo.JsExecuteBo;
import org.dromara.demo.service.IJsExecuteService;
import org.dromara.common.mybatis.core.page.TableDataInfo;

/**
 * execute
 *
 * @author zhu
 * @date 2025-01-02
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/demo/execute")
public class JsExecuteController extends BaseController {

    private final IJsExecuteService jsExecuteService;

    private final IJsFileService jsFileService;

    private final ISysUserService sysUserService;
    private final ISysDeptService  deptService; ;
    /**
     * 查询execute列表
     */
    @GetMapping("/list")
    public TableDataInfo<JsExecuteVo> list(JsExecuteBo bo, PageQuery pageQuery) {
        return jsExecuteService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出execute列表
     */
    @Log(title = "execute", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(JsExecuteBo bo, HttpServletResponse response) {
        List<JsExecuteVo> list = jsExecuteService.queryList(bo);
        ExcelUtil.exportExcel(list, "execute", JsExecuteVo.class, response);
    }

    /**
     * 获取execute详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<JsExecuteVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(jsExecuteService.queryById(id));
    }

    /**
     * 新增execute
     */
    @Log(title = "execute", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody JsExecuteBo bo) {
        return toAjax(jsExecuteService.insertByBo(bo));
    }

    /**
     * 修改execute
     */
    @Log(title = "execute", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody JsExecuteBo bo) {
        return toAjax(jsExecuteService.updateByBo(bo));
    }

    /**
     * 删除execute
     *
     * @param ids 主键串
     */
    @Log(title = "execute", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(jsExecuteService.deleteWithValidByIds(List.of(ids), true));
    }

    /**
     * 执行报告
     */
    @Log(title = "execute", businessType = BusinessType.EXPORT)
    @PostMapping("/exportReport")
    @SaIgnore
    public void exportReport(JsExecuteBo bo, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        SysUserVo sysUserVo = sysUserService.selectUserById(bo.getCreateBy());
        SysDeptVo sysDeptVo = deptService.selectDeptById(sysUserVo.getDeptId());
        map.put("id", bo.getId());
        map.put("ProjectNo",bo.getProjectNo()==null?"":bo.getProjectNo());
        map.put("ProjectName",bo.getProjectName()==null?"":bo.getProjectName());
        map.put("TesterName",sysUserVo.getNickName()==null?"":sysUserVo.getNickName());
        map.put("DepartmentName",sysDeptVo.getDeptName()==null?"":sysDeptVo.getDeptName());
        map.put("TestEnvironment", bo.getTestEnvironment()==null?"":bo.getTestEnvironment());
        map.put("ProductName", bo.getProductName()==null?"":bo.getProductName());
        map.put("documentInput", bo.getDocumentInput()==null?"":bo.getDocumentInput());
        map.put("testDescription", bo.getTestDescription()==null?"":bo.getTestDescription());
        map.put("comment", bo.getComment()==null?"":bo.getComment());
        map.put("designOpinion", bo.getDesignOpinion()==null?"":bo.getDesignOpinion());
        map.put("VersionNo", bo.getVersionNo()==null?"":bo.getVersionNo());
        map.put("TestRange",bo.getTestRange()==null?"":bo.getTestRange());
        // map转json 字符串
        String s = JSONObject.toJSONString(map);
        System.out.println(s);
        // Python解释器的路径
        String pythonInterpreter = "/Users/joron314/PycharmProjects/JohnsonControl-Hitachi/venv/bin/python"; // 或者指定完整路径，如 "C:\\Python39\\python.exe"

        // Python脚本的路径
        ProcessBuilder pb = new ProcessBuilder(pythonInterpreter,"/Users/joron314/PycharmProjects/JohnsonControl-Hitachi/venv/FloorStanding&HighWall/common/File_PDFReport.py", s);
        try {
            // 启动进程
            Process process = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待命令执行完成
            int i = process.waitFor();
            System.out.println(i);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        JsFileVo jsFile = jsFileService.queryByExecuteId(bo.getId(), "PDF");
        generateFile(response, jsFile.getFile(), bo.getSuiteName()+"_" + DateUtil.format(bo.getCreateTime(), "yyyyMMddHHmmss") + ".pdf");
    }

    /**
     * 执行报告
     */
    @Log(title = "execute", businessType = BusinessType.EXPORT)
    @PostMapping("/exportExReport")
    @SaIgnore
    public void exportExcelReport(JsExecuteBo bo, HttpServletResponse response) throws IOException {
        JsFileVo jsFile = jsFileService.queryByExecuteId(bo.getId(), "EXCEL");
        SysUserVo sysUserVo = sysUserService.selectUserById(bo.getCreateBy());
        String fileName = jsFile.getFileName();
        // 这里 会填充到第一个sheet， 然后文件流会自动关闭
        Map<String, Object> map = new HashMap<>();
        map.put("versionNo", bo.getVersionNo());
        map.put("Assignee", sysUserVo.getNickName());
        resetResponse("多列表.xlsx", response);
        ServletOutputStream os = response.getOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(os)
            .withTemplate(new File(fileName))
            .autoCloseStream(false)
            // 大数值自动转换 防止失真
            .registerConverter(new ExcelBigNumberConvert())
            .build();
        WriteSheet writeSheet = EasyExcel.writerSheet("5_Test Spec 3.4_IDU").build();
        if (CollUtil.isEmpty(CollUtil.newArrayList(map))) {
            throw new IllegalArgumentException("数据为空");
        }
        // 单表多数据导出 模板格式为 {.属性}
        for (Object d : CollUtil.newArrayList(map)) {
            excelWriter.fill(d, writeSheet);
        }
        excelWriter.finish();
    }
    public static String encodingFilename(String filename) {
        return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
    }
    private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException {
        String filename = encodingFilename(sheetName);
        FileUtils.setAttachmentResponseHeader(response, filename);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
    }


    private void generateFile(HttpServletResponse response, byte[] data, String fileName) {
        response.setHeader("content-Type", "application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        try {
            response.getOutputStream().write(data);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                response.getOutputStream().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
